﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using System.Xml.XPath;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server.Search.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace Microsoft.SPF.UI.WebParts
{
    [ToolboxItemAttribute(false)]
    public class EnhancedRefinementWebPart : RefinementWebPart
    {
        internal static String DefaultSettingsXml
        {
            get
            {
                StreamReader sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.xml.EnhancedRefinementSettings.xml"));
                string s = sr.ReadToEnd();
                sr.Close();
                return s;
            }
        }

        internal static String DefaultXsl
        {
            get
            {
                StreamReader sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.xml.DefaultStyleSheet.xslt"));
                string s = sr.ReadToEnd();
                sr.Close();
                return s;
            }
        }

        internal static String DefaultFilterCategoriesDefinition
        {
            get
            {
                StreamReader sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.xml.DefaultFilterCategories.xml"));
                string s = sr.ReadToEnd();
                sr.Close();
                return s;
            }
        }

        private String chartSettingsDefinition;

        #region 拡張プロパティ

        [WebBrowsable(true), Category("絞り込み"), FriendlyName("拡張絞り込みの定義"),
        Personalizable(PersonalizationScope.Shared),
        Description("拡張絞り込みの XML 定義"), WebPartStorage(Storage.Shared)]
        public String EnhancedRefinementSettingsDefinition
        {
            get
            {
                return chartSettingsDefinition;
            }
            set
            {
                chartSettingsDefinition = value;
            }
        }

        #endregion

        private TaxonomySession session = null;
        private XmlDocument baseSettings = null;

        public override string GetDefaultConfiguration(Location location)
        {
            return EnhancedRefinementWebPart.DefaultFilterCategoriesDefinition; 
            //return string.Format(CultureInfo.CurrentUICulture, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<FilterCategories>\r\n  <Category\r\n    Title=\"{0}\"\r\n    Description=\"{1}\"\r\n    Type=\"Microsoft.Office.Server.Search.WebControls.RankingModelFilterGenerator\"\r\n    MetadataThreshold=\"3\"\r\n    NumberOfFiltersToDisplay=\"3\"    \r\n    ShowMoreLink=\"False\"\r\n    MappedProperty=\"\"/>\r\n  <Category\r\n    Title=\"spshjobtitle\"\r\n    Description=\"{2}\"\r\n    Type=\"Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator\"\r\n    MetadataThreshold=\"3\"\r\n    NumberOfFiltersToDisplay=\"3\"\r\n    MaxNumberOfFilters=\"50\"    \r\n    ShowMoreLink=\"True\"\r\n    MappedProperty=\"ows_MetadataFacetInfo\"\r\n    MoreLinkText=\"{7}\"    \r\n    LessLinkText=\"{8}\"/> \r\n  <Category    \r\n    Title=\"{3}\"    \r\n    Description=\"{4}\"    \r\n    Type=\"Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator\"    \r\n    MetadataThreshold=\"5\"    \r\n    NumberOfFiltersToDisplay=\"4\"    \r\n    MaxNumberOfFilters=\"50\"    \r\n    SortBy=\"Frequency\"    \r\n    SortDirection=\"Descending\"\r\n    SortByForMoreFilters=\"Name\"\r\n    SortDirectionForMoreFilters=\"Ascending\"\r\n    ShowMoreLink=\"True\"    \r\n    MappedProperty=\"OrgNames\"    \r\n    MoreLinkText=\"{7}\"    \r\n    LessLinkText=\"{8}\"/> \r\n  <Category\r\n    Title=\"{5}\"\r\n    Description=\"{6}\"\r\n    Type=\"Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator\"\r\n    MetadataThreshold=\"3\"\r\n    NumberOfFiltersToDisplay=\"3\"\r\n    MaxNumberOfFilters=\"50\"    \r\n    ShowMoreLink=\"True\"\r\n    MappedProperty=\"ows_MetadataFacetInfo\"\r\n    MoreLinkText=\"{7}\"    \r\n    LessLinkText=\"{8}\"/> \r\n</FilterCategories>", new object[] { SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_Focus)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_FocusDescription)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_JobTitleDescription)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_Organization)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_OrganizationDescription)), SPHttpUtility.HtmlEncode("Managed Metadata Columns"), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_ManagedMetadataDescription)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_MoreLinkLabel)), SPHttpUtility.HtmlEncode(StringResourceManager.GetString(LocStringId.RefinementPanel_OOBConfig_LessLinkLabel)) });
        }

        protected override void OnInit(EventArgs e)
        {
            session = new TaxonomySession(SPContext.Current.Site);

            if (this.UseDefaultConfiguration || string.IsNullOrEmpty(this.EnhancedRefinementSettingsDefinition))
            {
                this.EnhancedRefinementSettingsDefinition = EnhancedRefinementWebPart.DefaultSettingsXml;
            }

            //データ ビューのxslが定義有無
            Boolean xslIsEmpty = string.IsNullOrEmpty(this.Xsl);

            //既定の値を利用する場合
            if (this.UseDefaultConfiguration)
            {
                this.DisplayedCategories = 10;
            } 
            base.OnInit(e);

            //データ ビューのxsl定義の上書き
            if (this.UseDefaultConfiguration || xslIsEmpty)
            {
                this.Xsl = EnhancedRefinementWebPart.DefaultXsl;
            }

            baseSettings = new XmlDocument();
            baseSettings.LoadXml(this.FilterCategoriesDefinition);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            CssRegistration.Register("/_layouts/EnhancedRefinementWebPart/styles.css");

            if (Page.ClientScript.IsClientScriptBlockRegistered("jquery") == false)
            {
                string js = Page.ClientScript.GetWebResourceUrl(this.GetType(), "Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.js.jquery-1.3.2.min.js");
                Page.ClientScript.RegisterClientScriptInclude("jquery", js);
            }

            if (Page.ClientScript.IsClientScriptBlockRegistered(this.ID + "MultiSelectRefiner") == false)
            {
                string js = Page.ClientScript.GetWebResourceUrl(this.GetType(), "Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.js.MultiSelectRefiner.js");
                Page.ClientScript.RegisterClientScriptInclude(this.ID + "MultiSelectRefiner", js);
                js =  Page.ClientScript.GetWebResourceUrl(this.GetType(), "Microsoft.SPF.UI.WebParts.EnhancedRefinementWebPart.js.jquery_MultiSelectRefiner.js");
                Page.ClientScript.RegisterClientScriptInclude(this.ID + "jqueryMultiSelectRefiner", js);
            }
        }

        protected override XPathNavigator GetXPathNavigator(string viewPath)
        {
            XPathNavigator nav = base.GetXPathNavigator(viewPath);
            if (nav == null) return nav;

            //"Chart"のプロパティを取得

            XmlDocument settingsDoc = new XmlDocument();
            settingsDoc.LoadXml(chartSettingsDefinition);

            //"Chart"型リファイナー作成
            XmlNodeList settingsNodeList = settingsDoc.SelectNodes("/EnhancedRefinementSettings/Refinements/Refinement[@Type=\"Chart\"]");
            XPathNavigator xnav;

            foreach(XmlNode settingsNode in settingsNodeList)
            {
                xnav = null;
                xnav = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + settingsNode.Attributes["ManagedProperty"].Value + "\"]");

                if (xnav != null)
                {
                    //グラフイメージの挿入
                    xnav.AppendChildElement(String.Empty, "EnhancedHtml", String.Empty, 
                    RenderChartHtml(xnav, settingsNode));
                    xnav.CreateAttribute(String.Empty, "IsEnhanced", String.Empty, "true");
                } 
            }

            //"Range"型リファイナー作成
            settingsNodeList = settingsDoc.SelectNodes("/EnhancedRefinementSettings/Refinements/Refinement[@Type=\"HistogramRange\"]");

            foreach (XmlNode settingsNode in settingsNodeList)
            {
                xnav = null;
                xnav = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + settingsNode.Attributes["ManagedProperty"].Value + "\"]");

                if (xnav != null)
                {
                    //グラフイメージの挿入
                    xnav.AppendChildElement(String.Empty, "EnhancedHtml", String.Empty,
                    RenderHistogramRangeHtml(xnav, settingsNode));
                    xnav.CreateAttribute(String.Empty, "IsEnhanced", String.Empty, "true");
                    xnav.CreateAttribute(String.Empty, "HideAny", String.Empty, "true");
                }
            }

            // "ClosedVocabulary"型リファイナー作成
            settingsNodeList = settingsDoc.SelectNodes("/EnhancedRefinementSettings/Refinements/Refinement[@Type=\"ClosedVocabulary\"]");
            foreach (XmlNode settingsNode in settingsNodeList)
            {
                // XSLにより、チェックボックスの表示を行う。SelectionType(Single:標準/MultiValue:チェックボックス付)
                string type = "Single";
                bool flag = true;
                if(settingsNode.Attributes.GetNamedItem("SelectionType")!=null) {
                    type = settingsNode.Attributes.GetNamedItem("SelectionType").Value;
                    flag = Boolean.Parse(settingsNode.Attributes.GetNamedItem("IsHidden").Value);
                }
                AddClosedVocabularyRefiner(nav, settingsNode, type,flag);
            }

            // 標準リファイナー作成
            settingsNodeList = settingsDoc.SelectNodes("/EnhancedRefinementSettings/Refinements/Refinement[@Type=\"Collapsed\"]");
            foreach (XmlNode settingsNode in settingsNodeList)
            {
                AddCollapsedRefiner(nav, settingsNode);
            }

            return nav;
        }

        private void AddClosedVocabularyRefiner(XPathNavigator nav, XmlNode settingsNode, string type,bool flag)
        {
            XPathNavigator refinernav = null;
            XPathNavigator refinernavmore = null;
            int refinercount = 0;
            int refinercountmore = 0;
            string mp = settingsNode.SelectNodes("ManagedProperty").Item(0).InnerText;
            
            string group = null;
            string termset = null;
            
            try
            {
                group = settingsNode.SelectNodes("TermStoreGroup").Item(0).InnerText;
                termset = settingsNode.SelectNodes("TermStoreTermset").Item(0).InnerText;
            }
            catch{}

            refinernav = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]/Filters");

            // "SelectionType"属性の追加(この属性によりチェックボックスによる複数選択を実現)
            XPathNavigator filterCategory = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]");
            if (filterCategory != null)
            {
                filterCategory.CreateAttribute(String.Empty, "SelectionType", String.Empty, type);
                if(flag)
                    filterCategory.CreateAttribute(String.Empty, "Collapsed", String.Empty, "true"); 
            }

            if (refinernav != null && refinernav.SelectChildren("Filter", String.Empty) != null)
            {
                refinernav.CreateAttribute(String.Empty, "Selection", String.Empty, type);
                refinercount = refinernav.SelectChildren("Filter", String.Empty).Count;


                #region //Selection="Implied"で選択済みとする

                XPathNodeIterator it = filterCategory.Select("./Filters/Filter");
                XPathNodeIterator itChildren;

                Location location = SharedQueryManager.GetInstance(this.Page).QueryManager[0][0];
                QueryInfo queryInfo = location.QueryInfo;
                string baseURL = queryInfo.ResultsUrl;
                //URL書式:"http://.../Pages/results.aspx?k=%23&a=<管理プロパティ>:XXXX AND <管理プロパティ>:xxxx..."

                Array arrURL = baseURL.Split('&');
                ArrayList ckURL = new ArrayList();

                #region MyRegion
                foreach (string temp in arrURL) 
                {
                    //%20AND%20
                    if (temp != string.Empty){
                        if (temp != "=") 
                        { 
                            if (temp.Substring(0, 2) == "a=") 
                            {
                                string replaceString = temp.Replace(" AND ", ",");
                                string[] tempCkURL = replaceString.Split(',');
                                tempCkURL[0] = tempCkURL[0].Substring(2);
                                for (int i = 0; i < tempCkURL.Length; i++) 
                                {
                                    if(tempCkURL[i].Length != 0)
                                        if (tempCkURL[i].Substring(0, mp.Length) == mp)
                                            ckURL.Add(tempCkURL[i]);
                                }
                            }
                        }
                    }
                }
                #endregion


                bool isFirst = true;

                while (it.MoveNext())
                {
                    if (isFirst)
                    {
                        it.Current.CreateAttribute(String.Empty, "isFirst", String.Empty, Convert.ToString(isFirst));
                        isFirst = false;
                    }

                    string tooltipValue = "";
                    itChildren = it.Current.SelectChildren(XPathNodeType.Element);
                    while (itChildren.MoveNext())
                    {
                        switch (itChildren.Current.LocalName)
                        {
                            case "Tooltip":
                                tooltipValue = itChildren.Current.Value;
                                break;

                            case "Selection":
                                foreach (string refineValue in ckURL) 
                                {
                                    if(HttpUtility.UrlDecode(refineValue).Contains(tooltipValue))
                                        itChildren.Current.InnerXml = "Implied";
                                }
                                break;

                            default:
                                break;
                        }
                    }
                }
                #endregion

            }

            //表示件数を増やす
            refinernavmore = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]/MoreFilters");

            if (refinernavmore != null && refinernavmore.SelectChildren("Filter", String.Empty) != null)
            {
                refinercountmore = refinernavmore.SelectChildren("Filter", String.Empty).Count;
            }


            List<string> terms = new List<string>();

            if (group != null || termset !=null)
                terms = GetTerms(group, termset);

            if (refinernav != null)
            {
                int NumberOfFiltersToDisplay = baseSettings.SelectSingleNode("/FilterCategories/Category[@MappedProperty=\"" + mp + "\"]/@NumberOfFiltersToDisplay") == null ? 6 : Int32.Parse(baseSettings.SelectSingleNode("/FilterCategories/Category[@MappedProperty=\"" + mp + "\"]/@NumberOfFiltersToDisplay").Value);
                int MaxNumberOfFilters = baseSettings.SelectSingleNode("/FilterCategories/Category[@MappedProperty=\"" + mp + "\"]/@MaxNumberOfFilters") == null ? 20 : Int32.Parse(baseSettings.SelectSingleNode("/FilterCategories/Category[@MappedProperty=\"" + mp + "\"]/@MaxNumberOfFilters").Value);

                XPathNavigator t = null;
                XPathNavigator tm = null;

                #region

                foreach (string term in terms)
                {
                    t = null;
                    tm = null;
                    t = refinernav.SelectSingleNode("Filter/Tooltip[.='" + term + "']");

                    // "表示数を増やす"をクリックにより、全件表示
                    if (refinernavmore != null)
                    {
                        tm = refinernavmore.SelectSingleNode("Filter/Tooltip[.='" + term + "']");
                    }

                    // 該当の用語セットが存在しない
                    if (t == null)
                    {
                        // "表示数を増やす"が不要の場合
                        if (tm == null)
                        {
                            if (refinercount <= NumberOfFiltersToDisplay)
                            {
                                XmlWriter newFilter = refinernav.AppendChild();
                                AddNullFilter(newFilter, term);
                                newFilter.Close();
                                refinercount++;
                            }
                            else
                            {
                                if (refinernavmore == null)
                                { // "表示数を増やす"を要する場合
                                    XPathNavigator allFilters = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]");
                                    XmlWriter moreFilter = allFilters.AppendChild();
                                    moreFilter.WriteStartElement("MoreFilters");
                                    moreFilter.WriteEndElement();
                                    moreFilter.Close();
                                    refinernavmore = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]/MoreFilters");

                                    moreFilter = refinernavmore.AppendChild();
                                    foreach (XPathNavigator filter in refinernav.SelectChildren("Filter", String.Empty))
                                    {
                                        moreFilter.WriteNode(filter, false);
                                        refinercountmore++;
                                    }
                                    moreFilter.Close();

                                }
                            }
                            if (refinernavmore != null && (refinercountmore <= MaxNumberOfFilters))
                            {
                                XmlWriter newFilter = refinernavmore.AppendChild();
                                AddNullFilter(newFilter, term);
                                newFilter.Close();
                                refinercountmore++;
                            }
                        }
                    }
                }
                #endregion

            }
        }
      
        private void AddCollapsedRefiner(XPathNavigator nav, XmlNode settingsNode)
        {
            XPathNavigator refinernav = null;
            string mp = settingsNode.Attributes.GetNamedItem("ManagedProperty").Value.ToString();
            refinernav = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]/Filters");

            // XSLTに従いリファイナー項目の追加(標準リファイナー)
            XPathNavigator filterCategory = nav.SelectSingleNode("/FilterPanel/FilterCategory[@ManagedProperty=\"" + mp + "\"]");
            if (filterCategory != null)
            {
                filterCategory.CreateAttribute(String.Empty, "Collapsed", String.Empty, "true");
            }
        }

        //返却xmlよりチャートの作成
        private Microsoft.Office.Server.WebControls.Chart GenerateChart(XPathNavigator refinementNav, XmlNode settingsNode)
        {
            Microsoft.Office.Server.WebControls.Chart chart = new Microsoft.Office.Server.WebControls.Chart();
            
            //データ ポイントおよび系列の要素を設定
            Series series = new Series();
            series.ChartType = (SeriesChartType)Enum.Parse(typeof(SeriesChartType),
                settingsNode.Attributes["ChartType"].Value, true);

            if (settingsNode.Attributes["ShowLegend"] == null || Convert.ToBoolean(settingsNode.Attributes["ShowLegend"].Value) == true) 
            {
                Legend legend = new Legend("Default");
                legend.Docking = Docking.Bottom;
                legend.BackColor = System.Drawing.Color.FromArgb(234, 238, 241);
                legend.TextWrapThreshold = 15;

                chart.Legends.Add(legend);
            }

            DataPoint dp;

            XPathNodeIterator it = refinementNav.Select("./Filters/Filter");
            XPathNodeIterator itChildren;
            while(it.MoveNext())
            {
                dp = new DataPoint();
                itChildren = it.Current.SelectChildren(XPathNodeType.Element);
                
                Boolean notAnyResultType = false;

                #region 検索情報の取得
                while (itChildren.MoveNext())
                {
                    switch (itChildren.Current.LocalName)
                    {
                        case "Value":
                            dp.Label = itChildren.Current.Value;

                            //DataPointの設定
                            SetDataPointSettings(dp, settingsNode, itChildren.Current.Value);
                            break;

                        case "Tooltip":
                            dp.ToolTip = itChildren.Current.Value;
                            break;

                        case "Count":
                            Int64 count;
                            if (!String.IsNullOrEmpty(itChildren.Current.Value) &&
                                Int64.TryParse(itChildren.Current.Value, out count))
                            {
                                notAnyResultType = true;
                                dp.SetValueY(count);
                            }
                            break;

                        case "Url":
                            dp.Url = itChildren.Current.Value;
                            break;

                        default:
                            break;
                    }
                }
                #endregion

                if (notAnyResultType) series.Points.Add(dp);
            }

            ChartArea area = new ChartArea();

            if (settingsNode.Attributes["IsReSortRequired"] == null || Convert.ToBoolean(settingsNode.Attributes["IsReSortRequired"].Value == "false"))
            {
                series.Sort(PointSortOrder.Descending);
            }
            else
            {
                series.Sort(PointSortOrder.Ascending);
            }

            //Seriesの設定
            SetSeriesSettings(series, settingsNode.SelectNodes("./Series/*"));
            series.LabelBackColor = System.Drawing.Color.FromArgb(234, 238, 241);

            //ChartAreaの設定
            SetChartAreaSettings(area, settingsNode.SelectNodes("./ChartArea/*"));
            area.BackColor = System.Drawing.Color.FromArgb(234, 238, 241);

            chart.ChartAreas.Add(area);
            chart.Series.Add(series);
            
            return chart;
        }

        #region 設定XMLによる設定

        //設定XMLによるChartAreaの設定
        private void SetChartAreaSettings(ChartArea area, XmlNodeList xmlNodeList)
        {
            foreach (XmlNode node in xmlNodeList)
            {
                switch (node.Attributes["name"].Value)
                {
                    case "IsUse3DView":
                        area.Area3DStyle.Enable3D = Convert.ToBoolean(node.Attributes["value"].Value);
                        break;
                }
            }
        }

        //設定XMLによるSeriesの設定
        private void SetSeriesSettings(Series series, XmlNodeList xmlNodeList)
        {
            foreach (XmlNode node in xmlNodeList)
            {
                switch (node.LocalName)
                {
                    case "Add":
                    case "add":
                        series[node.Attributes["name"].Value] = node.Attributes["value"].Value;
                        break;

                    default:
                        break;
                 }
            }
        }

        //設定XMLによるDataPointの設定
        private void SetDataPointSettings(DataPoint dp, XmlNode settings, String value)
        {
            XmlNode dpSetting = settings.SelectSingleNode("./DataPoints/Add[@value=\"" + value + "\"]");

            if (dpSetting != null)
            {
                String colorStr = dpSetting.Attributes["color"].Value;

                if (!String.IsNullOrEmpty(colorStr))
                {
                    dp.Color = System.Drawing.Color.FromName(colorStr);
                }
            }
        }

        #endregion

        private HistogramRangeRefinementControl GenerateRangeHistogram(XPathNavigator refinementNav, XmlNode settingsNode)
        {
            HistogramRangeRefinementControl ctrl = new Microsoft.SPF.UI.WebParts.HistogramRangeRefinementControl();

            ctrl.ID = "SPFHRR";

            #region 設定XMLによる設定

            #region Color,BackImageWrapMode,BackImageの設定

            if (settingsNode.Attributes["cropColor"] == null)
            {
                ctrl.CropColor = System.Drawing.Color.Red;
            }
            else
            {
                ctrl.CropColor = System.Drawing.Color.FromName(settingsNode.Attributes["cropColor"].Value);
            }


            if (settingsNode.Attributes["backImageWrapMode"] != null)
            {
                ctrl.BackImageWrapMode = settingsNode.Attributes["backImageWrapMode"].Value;
            }
            else
            {
                ctrl.BackImageWrapMode = "Tile";
            }

            if (settingsNode.Attributes["backImage"] != null)
            {
                ctrl.BackImage = settingsNode.Attributes["backImage"].Value;
            }
            else
            {
                ctrl.BackImage = "/_layouts/images/EnhancedRefinementWebPart/bar4.jpg";
            }

            #endregion

            #region CSS周りの設定

            if (settingsNode.Attributes["parentCssClass"] != null)
            {
                ctrl.CssClass = settingsNode.Attributes["parentCssClass"].Value;
            } 
            else
            {
                ctrl.CssClass = "searchdaterange01";
            }

            if (settingsNode.Attributes["histogramCssClass"] != null)
            {
                ctrl.HistogramCssClass = settingsNode.Attributes["histogramCssClass"].Value;
            } 
            else
            {
                ctrl.HistogramCssClass = "lr_a";
            }

            if (settingsNode.Attributes["leftHistogramLayerCssClass"] != null)
            {
                ctrl.LeftHistogramLayerCssClass = settingsNode.Attributes["leftHistogramLayerCssClass"].Value;
            } 
            else
            {
                ctrl.LeftHistogramLayerCssClass = "lr_b_1";
            }

            if (settingsNode.Attributes["rightHistogramLayerCssClass"] != null)
            {
                ctrl.RightHistogramLayerCssClass = settingsNode.Attributes["rightHistogramLayerCssClass"].Value;
            } 
            else
            {
                ctrl.RightHistogramLayerCssClass = "lr_b_2";
            }

            if (settingsNode.Attributes["sliderCssClass"] != null)
            {
                ctrl.SliderCssClass = settingsNode.Attributes["sliderCssClass"].Value;
            } 
            else
            {
                ctrl.SliderCssClass = "slidebar";
            }

            if (settingsNode.Attributes["leftBarCssClass"] != null)
            {
                ctrl.LeftBarCssClass = settingsNode.Attributes["leftBarCssClass"].Value;
            } 
            else
            {
                ctrl.LeftBarCssClass = "barfader_l";
            }

            if (settingsNode.Attributes["rightBarCssClass"] != null)
            {
                ctrl.RightBarCssClass = settingsNode.Attributes["rightBarCssClass"].Value;
            } 
            else
            {
                ctrl.RightBarCssClass = "barfader_r";
            }

            if (settingsNode.Attributes["leftSliderCssClass"] != null)
            {
                ctrl.LeftSliderCssClass = settingsNode.Attributes["leftSliderCssClass"].Value;
            } 
            else
            {
                ctrl.LeftSliderCssClass = "sl";
            }

            if (settingsNode.Attributes["rightSliderCssClass"] != null)
            {
                ctrl.RightSliderCssClass = settingsNode.Attributes["rightSliderCssClass"].Value;
            } 
            else
            {
                ctrl.RightSliderCssClass = "sr";
            }

            if (settingsNode.Attributes["sliderValueCssClass"] != null)
            {
                ctrl.SliderValueCssClass = settingsNode.Attributes["sliderValueCssClass"].Value;
            } 
            else
            {
                ctrl.SliderValueCssClass = "slider_years";
            }

            if (settingsNode.Attributes["leftSliderValueCssClass"] != null)
            {
                ctrl.LeftSliderValueCssClass = settingsNode.Attributes["leftSliderValueCssClass"].Value;
            } 
            else
            {
                ctrl.LeftSliderValueCssClass = "year_l";
            }

            if (settingsNode.Attributes["rightSliderValueCssClass"] != null)
            {
                ctrl.RightSliderValueCssClass = settingsNode.Attributes["rightSliderValueCssClass"].Value;
            } 
            else
            {
                ctrl.RightSliderValueCssClass = "year_r";
            }

            if (settingsNode.Attributes["leftSliderId"] != null)
            {
                ctrl.LeftSliderId = settingsNode.Attributes["leftSliderId"].Value;
            } 
            else
            {
                ctrl.LeftSliderId = "year1";
            }

            if (settingsNode.Attributes["rightSliderId"] != null)
            {
                ctrl.RightSliderId = settingsNode.Attributes["rightSliderId"].Value;
            } 
            else
            {
                ctrl.RightSliderId = "year2";
            }


            if (settingsNode.Attributes["cropOpacity"] == null)
            {
                ctrl.CropOpacity = 65;
            }
            else
            {
                ctrl.CropOpacity = Int32.Parse(settingsNode.Attributes["cropOpacity"].Value);
            }

            if (settingsNode.Attributes["showLabel"] == null)
            {
                ctrl.ShowLabel = true;
            }
            else
            {
                ctrl.ShowLabel = Boolean.Parse(settingsNode.Attributes["showLabel"].Value);
            }

            #endregion

            #endregion

            ctrl.ManagedPropertyName = refinementNav.GetAttribute("ManagedProperty", String.Empty);

            Microsoft.SPF.UI.WebControls.RefinementItem ri;

            #region 各値の設定

            XPathNodeIterator it = refinementNav.Select("./Filters/Filter");
            XPathNodeIterator itChildren;
            while (it.MoveNext())
            {
                ri = new Microsoft.SPF.UI.WebControls.RefinementItem();

                itChildren = it.Current.SelectChildren(XPathNodeType.Element);

                Boolean notAnyResultType = false;

                while (itChildren.MoveNext())
                {
                    switch (itChildren.Current.LocalName)
                    {
                        case "Tooltip":
                            ri.Modifier = itChildren.Current.Value; 
                            ri.Label = ParseRangeValue(itChildren.Current.Value);
                            break;

                        case "Count":
                            Int64 count;
                            if (!String.IsNullOrEmpty(itChildren.Current.Value) &&
                                Int64.TryParse(itChildren.Current.Value, out count))
                            {
                                notAnyResultType = true;
                                ri.Value = count;
                            }
                            break;

                        default:
                            break;
                    }
                }

                if (notAnyResultType) ctrl.RefinementCollection.Add(ri);

            }
            #endregion

            return ctrl;
        }

        //datetime型の設定値をparse
        private string ParseRangeValue(string refinementValue)
        {
            String[] chunks = refinementValue.Trim().Split(' ');

            if (chunks.Length == 0) return refinementValue.Trim();

            DateTime lowerDt = DateTime.MinValue, upperDt = DateTime.MaxValue;
            Double lowerD = Double.MinValue, upperD = Double.MaxValue;
            bool isUpperDate = false;
            bool isLowerDate = false;
            bool isUpperNumber = false;
            bool isLowerNumber = false;

            for (int i = 0; i < chunks.Length; i++)
            {
                if (DateTime.TryParse(chunks[i], out lowerDt))
                {
                    isLowerDate = true;
                    lowerDt = lowerDt.ToUniversalTime();
                }

                if (!isLowerDate)
                {
                    if (Double.TryParse(chunks[i], out lowerD)) isLowerNumber = true;
                }

                if (isLowerDate || isLowerNumber) break;
            }

            for (int i = chunks.Length - 1; i >= 0; i--)
            {
                if (DateTime.TryParse(chunks[i], out upperDt))
                {
                    isUpperDate = true;
                    upperDt = upperDt.ToUniversalTime();
                }

                if (!isLowerDate)
                {
                    if (Double.TryParse(chunks[i], out upperD)) isUpperNumber = true;
                }

                if (isUpperDate || isUpperNumber) break;
            }
            
            if (isLowerDate || isUpperDate)
            {
                StringBuilder sb = new StringBuilder();
                if (isLowerDate)           
                    sb.Append(lowerDt.ToString("yyyy/MM/dd/HH:mm:ss", CultureInfo.InvariantCulture));

                sb.Append("|");

                if (isUpperDate)
                    sb.Append(upperDt.ToString("yyyy/MM/dd/HH:mm:ss", CultureInfo.InvariantCulture));
                return sb.ToString();
            }

            if (isLowerNumber || isUpperNumber)
            {
                StringBuilder sb = new StringBuilder();
                if (isLowerNumber)
                {
                    sb.Append(lowerD.ToString());
                }
                else if (isUpperNumber)  {
                    sb.Append(upperD.ToString());
                // sb.Append("|");
                }
              
                return sb.ToString();
            }

            return refinementValue;
        }

        //ユーザーチャートコントロールの設定
        private String RenderChartHtml(XPathNavigator refinementNav, XmlNode settingsNode)
        {
            //系、要素の取得
            Chart chart = GenerateChart(refinementNav, settingsNode);
            StringBuilder sb = new StringBuilder();

            //usemapの対応付の為、IDを設定(一意とする)
            chart.ID = settingsNode.Attributes["ManagedProperty"].Value;

            chart.Page = this.Page;

            chart.Width = Unit.Pixel(Int32.Parse(settingsNode.Attributes["Width"].Value));
            chart.Height = Unit.Pixel(Int32.Parse(settingsNode.Attributes["Height"].Value));
            chart.BackColor = System.Drawing.Color.FromArgb(234, 238, 241);

            using (StringWriter stringWriter = new StringWriter(sb))
            {
                using (HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter))
                {
                    //グラフを描画
                    chart.RenderControl(htmlWriter);
                }
            }

            return sb.ToString();
        }

        private String RenderHistogramRangeHtml(XPathNavigator refinementNav, XmlNode settingsNode)
        {
            HistogramRangeRefinementControl hrr = GenerateRangeHistogram(refinementNav, settingsNode);
            StringBuilder sb = new StringBuilder();

            hrr.Page = this.Page;

            Int32 width = Int32.Parse(settingsNode.Attributes["Width"].Value) - 10;
            Int32 height = Int32.Parse(settingsNode.Attributes["Height"].Value);

            hrr.Width = Unit.Pixel(width);
            hrr.Height = Unit.Percentage(100);
            hrr.Style.Add("margin-left", "10px");

            using (StringWriter stringWriter = new StringWriter(sb))
            {
                using (HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter))
                {
                    //グラフを描画
                    hrr.DoPrep();
                    hrr.RenderControl(htmlWriter);
                }
            }

            return "<div style=\"width:" + (width+10) +"px;\" class=\"histogramContainer\">" +sb.ToString()+"</div>";
        }

        private void AddNullFilter(XmlWriter newFilter, string term)
        {
            newFilter.WriteStartElement("Filter");

            newFilter.WriteStartElement("Value");
            newFilter.WriteString(term);
            newFilter.WriteEndElement();

            newFilter.WriteStartElement("Tooltip");
            newFilter.WriteString(term);
            newFilter.WriteEndElement();

            newFilter.WriteStartElement("Url");
            newFilter.WriteEndElement();

            newFilter.WriteStartElement("Selection");
            newFilter.WriteString("Static");
            newFilter.WriteEndElement();

            newFilter.WriteStartElement("Count");
            newFilter.WriteString("0");
            newFilter.WriteEndElement();

            newFilter.WriteStartElement("Percentage");
            newFilter.WriteString("0");
            newFilter.WriteEndElement();

            newFilter.WriteEndElement();
        }

        private List<string> GetTerms(string groupName, string termSet)
        {
            List<string> result = new List<string>();
            if (groupName == null || termSet == null) return result;

            foreach (Group group in session.DefaultKeywordsTermStore.Groups)
            {
                if (group.Name.ToLower().Equals(groupName.ToLower()))
                {
                    foreach (TermSet set in group.TermSets)
                    {
                        if (set.Name.ToLower().Equals(termSet.ToLower()))
                        {
                            foreach (Term term in set.Terms)
                            {
                                result.Add(term.Name);
                            }
                        }
                    }
                }
            }

            return result;
        }

    }
}
